// package main

// import (
// 	"fmt"
// 	"os"
// 	"strconv"
// 	"time"

// 	"github.com/shirou/gopsutil/v3/disk"
// 	"github.com/shirou/gopsutil/v3/net"
// )

// // 获取网卡理论带宽（单位：字节/秒）
// func getInterfaceSpeed(iface string) (uint64, error) {
// 	// /sys/class/net/<iface>/speed 单位为 Mbps
// 	path := fmt.Sprintf("/sys/class/net/%s/speed", iface)
// 	data, err := os.ReadFile(path)
// 	if err != nil {
// 		return 0, err
// 	}

// 	// 转换为字节/秒 (1 Mbps = 125000 字节/秒)
// 	speedMbps, _ := strconv.ParseUint(string(data[:len(data)-1]), 10, 64)
// 	return speedMbps * 125000, nil
// }

// // 计算网络IO占比
// func calculateNetUsage(prev, curr net.IOCountersStat, speed uint64) (float64, float64) {
// 	sentBytes := curr.BytesSent - prev.BytesSent
// 	recvBytes := curr.BytesRecv - prev.BytesRecv

// 	sentUsage := float64(sentBytes) / float64(speed) * 100
// 	recvUsage := float64(recvBytes) / float64(speed) * 100

// 	return sentUsage, recvUsage
// }

// // 计算磁盘IO占比（活跃时间百分比）
// func calculateDiskUsage(prev, curr disk.IOCountersStat, intervalSec uint64) float64 {
// 	ioTime := curr.IoTime - prev.IoTime
// 	return float64(ioTime) / float64(intervalSec*1000) * 100 // IoTime 单位为毫秒
// }

// // 格式化带宽显示
// func formatBandwidth(bytes uint64) string {
// 	const (
// 		KB = 1 << 10
// 		MB = 1 << 20
// 		GB = 1 << 30
// 	)

// 	switch {
// 	case bytes >= GB:
// 		return fmt.Sprintf("%.2f GB/s", float64(bytes)/GB)
// 	case bytes >= MB:
// 		return fmt.Sprintf("%.2f MB/s", float64(bytes)/MB)
// 	case bytes >= KB:
// 		return fmt.Sprintf("%.2f KB/s", float64(bytes)/KB)
// 	default:
// 		return fmt.Sprintf("%d B/s", bytes)
// 	}
// }

// func main() {
// 	interval := 5 * time.Second
// 	intervalSec := uint64(1)

// 	// 初始化网络统计
// 	prevNetStats, err := net.IOCounters(true)
// 	if err != nil {
// 		fmt.Printf("获取网络统计失败: %v\n", err)
// 		return
// 	}
// 	netMap := make(map[string]net.IOCountersStat)
// 	for _, stat := range prevNetStats {
// 		netMap[stat.Name] = stat
// 	}

// 	// 初始化磁盘统计
// 	prevDiskStats, err := disk.IOCounters()
// 	if err != nil {
// 		fmt.Printf("获取磁盘统计失败: %v\n", err)
// 		return
// 	}

// 	fmt.Println("开始监控 IO 占比 (按 Ctrl+C 退出)...")
// 	fmt.Println("===================================== 网络 IO 统计 =====================================")
// 	fmt.Printf("%-8s %-16s %-6s %-16s %-6s\n", "接口", "发送速率", "占比", "接收速率", "占比")

// 	fmt.Println("\n===================================== 磁盘 IO 统计 =====================================")
// 	fmt.Printf("%-8s %-12s %-6s\n", "设备", "IO 活跃时间", "占比")
// 	fmt.Println("--------------------------------------------------------------------------------------")

// 	ticker := time.NewTicker(interval)
// 	defer ticker.Stop()

// 	for range ticker.C {
// 		// 网络 IO 统计
// 		currNetStats, _ := net.IOCounters(true)
// 		for _, curr := range currNetStats {
// 			prev, exists := netMap[curr.Name]
// 			if !exists {
// 				continue
// 			}

// 			// 获取网卡理论带宽
// 			speed, err := getInterfaceSpeed(curr.Name)
// 			if err != nil {
// 				// 忽略无法获取带宽的接口（如 lo 回环）
// 				continue
// 			}

// 			// 计算速率和占比
// 			sentBytes := curr.BytesSent - prev.BytesSent
// 			recvBytes := curr.BytesRecv - prev.BytesRecv
// 			sentUsage, recvUsage := calculateNetUsage(prev, curr, speed)

// 			fmt.Printf("[网络] %-8s %-16s %-5.2f%% %-16s %-5.2f%%\n",
// 				curr.Name,
// 				formatBandwidth(sentBytes),
// 				sentUsage,
// 				formatBandwidth(recvBytes),
// 				recvUsage,
// 			)

// 			netMap[curr.Name] = curr
// 		}

// 		// 磁盘 IO 统计
// 		currDiskStats, _ := disk.IOCounters()
// 		for name, curr := range currDiskStats {
// 			prev, exists := prevDiskStats[name]
// 			if !exists {
// 				continue
// 			}

// 			// 计算磁盘活跃时间占比
// 			usage := calculateDiskUsage(prev, curr, intervalSec)
// 			ioTime := curr.IoTime - prev.IoTime

// 			fmt.Printf("[磁盘] %-8s %-12d ms %-5.2f%%\n",
// 				name,
// 				ioTime,
// 				usage,
// 			)

// 			prevDiskStats[name] = curr
// 		}

// 		fmt.Println("--------------------------------------------------------------------------------------")
// 	}
// }

package main

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"time"

	"github.com/shirou/gopsutil/v3/disk"
	"github.com/shirou/gopsutil/v3/net"
)

// 获取网卡理论带宽（单位：字节/秒）
func getInterfaceSpeed(iface string) (uint64, error) {
	//读取到的是 兆比特每秒（Mbps） 转换为 字节每秒
	path := fmt.Sprintf("/sys/class/net/%s/speed", iface)
	data, err := os.ReadFile(path)
	if err != nil {
		return 0, err
	}

	speedMbps, _ := strconv.ParseUint(string(data[:len(data)-1]), 10, 64)
	return speedMbps * 125000, nil // 转换为字节/秒
}

// 计算网络IO占比
func calculateNetUsage(prev, curr net.IOCountersStat, speed uint64) (float64, float64) {
	sentBytes := curr.BytesSent - prev.BytesSent
	recvBytes := curr.BytesRecv - prev.BytesRecv

	sentUsage := float64(sentBytes) / float64(speed) * 100
	recvUsage := float64(recvBytes) / float64(speed) * 100

	return sentUsage, recvUsage
}

// 格式化带宽显示
func formatBandwidth(bytes uint64) string {
	const (
		KB = 1 << 10
		MB = 1 << 20
		GB = 1 << 30
	)

	switch {
	case bytes >= GB:
		return fmt.Sprintf("%.2f GB/s", float64(bytes)/GB)
	case bytes >= MB:
		return fmt.Sprintf("%.2f MB/s", float64(bytes)/MB)
	case bytes >= KB:
		return fmt.Sprintf("%.2f KB/s", float64(bytes)/KB)
	default:
		return fmt.Sprintf("%d B/s", bytes)
	}
}

// 计算磁盘IO占比
func calculateDiskUsage(prev, curr disk.IOCountersStat, intervalSec int) float64 {
	ioTime := curr.IoTime - prev.IoTime
	return float64(ioTime) / float64(intervalSec*1000) * 100
}

func main() {
	interval := 5 * time.Second

	// 初始化网络统计
	prevNetStats, err := net.IOCounters(true)
	if err != nil {
		fmt.Printf("获取网络统计失败: %v\n", err)
		return
	}
	netMap := make(map[string]net.IOCountersStat)
	for _, stat := range prevNetStats {
		netMap[stat.Name] = stat
	}

	go statDisk()

	// 打印标题（使用固定宽度对齐）
	fmt.Println("=== 网络 IO 统计 ===")
	// 左对齐，固定宽度：接口(10) | 发送速率(16) | 占比(8) | 接收速率(16) | 占比(8)
	fmt.Printf("%-15s %-16s %-8s %-16s %-8s\n",
		"接口", "发送速率", "发送占比", "接收速率", "接收占比")
	fmt.Println("--------------------------------------------------------------------------")

	ticker := time.NewTicker(interval)
	defer ticker.Stop()

	for range ticker.C {
		// 网络 IO 统计
		currNetStats, _ := net.IOCounters(true)
		for _, curr := range currNetStats {
			prev, exists := netMap[curr.Name]
			if !exists {
				continue
			}

			speed, err := getInterfaceSpeed(curr.Name)
			if err != nil || speed == 0 {
				continue // 忽略无法获取带宽的接口
			}

			sentBytes := curr.BytesSent - prev.BytesSent
			recvBytes := curr.BytesRecv - prev.BytesRecv
			sentUsage, recvUsage := calculateNetUsage(prev, curr, speed)

			// 使用固定宽度格式化输出，确保对齐
			fmt.Printf("%-15s %-16s %-8.2f%% %-16s %-8.2f%%\n",
				curr.Name,
				formatBandwidth(sentBytes),
				sentUsage,
				formatBandwidth(recvBytes),
				recvUsage,
			)

			netMap[curr.Name] = curr
		}

		fmt.Println("--------------------------------------------------------------------------")
	}

}

func statDisk() {
	intervalSec := 1

	// 初始化磁盘统计
	prevDiskStats, err := disk.IOCounters()
	if err != nil {
		fmt.Printf("获取磁盘统计失败: %v\n", err)
		return
	}

	fmt.Println("\n=== 磁盘 IO 统计 ===")
	// 左对齐，固定宽度：设备(10) | 活跃时间(12) | 占比(8)
	fmt.Printf("%-15s %-12s %-8s\n",
		"设备", "活跃时间", "IO占比")
	fmt.Println("--------------------------------------------------------------------------")

	ticker := time.NewTicker(time.Duration(intervalSec) * time.Second)
	defer ticker.Stop()

	for range ticker.C {
		// 磁盘 IO 统计
		currDiskStats, _ := disk.IOCounters()
		for name, curr := range currDiskStats {
			prev, exists := prevDiskStats[name]
			if !exists {
				continue
			}

			usage := calculateDiskUsage(prev, curr, intervalSec)
			ioTime := curr.IoTime - prev.IoTime
			log.Println("curr=", curr)
			// 固定宽度格式化输出
			fmt.Printf("%-15s %-12d ms %-8.2f%%\n",
				name,
				ioTime,
				usage,
			)

			prevDiskStats[name] = curr
		}

		fmt.Println("--------------------------------------------------------------------------")
	}
}
